package cn.brilliantfuture.commentry.delivery.impl;

import java.rmi.RemoteException;
import java.text.MessageFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.jws.WebService;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.log4j.Logger;
import org.jboss.wsf.spi.annotation.WebContext;

import com.acsm.commons.sms.AlidayuSMS;
import com.acsm.commons.sms.SaveSmsInfo;

import cn.brilliantfuture.commentry.delivery.DeliveryMessageRemote;
import cn.brilliantfuture.commentry.delivery.DeliveryMessageWebService;
import cn.brilliantfuture.commentry.entity.DeliveryRecord;
import cn.brilliantfuture.commentry.entity.EmailInfo;
import cn.brilliantfuture.commentry.entity.Lockers;
import cn.brilliantfuture.commentry.entity.OrderInformation;
import cn.brilliantfuture.commentry.entity.PickRecords;
import cn.brilliantfuture.commentry.entity.ProductBatch;
import cn.brilliantfuture.commentry.entity.RefundPickRecords;
import cn.brilliantfuture.commentry.entity.SmsInfo;
import cn.brilliantfuture.commentry.entity.StorageGrid;
import cn.brilliantfuture.commentry.entity.StorageGridPurchaserNews;
import cn.brilliantfuture.commentry.inform.InformMessageLocal;
import cn.brilliantfuture.commentry.order.WorkflowMessageLocal;
import cn.brilliantfuture.commentry.util.CommEntryUtil;
import cn.brilliantfuture.commentry.util.DateTimeHelper;
import cn.brilliantfuture.commentry.util.EMAILScheduler;
import cn.brilliantfuture.commentry.util.SMSScheduler;
import cn.brilliantfuture.commentry.ws.shunxin.ResultInfo;
import cn.brilliantfuture.commentry.ws.shunxin.WebServiceSoapProxy;

/**
 * 
 * Title: Communication Entry
 * 
 * Author: LiTian
 * 
 * Date: 2011-10-25
 * 
 * Description: 送货流程管理
 * 
 */
@Stateless
@WebService(endpointInterface = "cn.brilliantfuture.commentry.delivery.DeliveryMessageWebService")
@WebContext(contextRoot = "/commentry", urlPattern = "/DeliveryMessageWebService")
public class DeliveryMessageImpl implements DeliveryMessageRemote, DeliveryMessageWebService {
	
	protected static final Logger logger = Logger.getLogger(DeliveryMessageImpl.class);

	@PersistenceContext(unitName = "commentry-jpa")
	private EntityManager entityManager;
	
	@EJB WorkflowMessageLocal workflowMessageLocal;

	@EJB InformMessageLocal informMessage;

	@SuppressWarnings("unchecked")
	public String[] deliveryWorkflow(String deviceSn, int gridNo, String rfidSn, String timestamp) {
		logger.info("DeliveryMessageImpl.deliveryWorkflow(String deviceSn, int gridNo, String rfidSn, String timestamp) ...");
		logger.info("deviceSN -> " + deviceSn + " gridId -> " + gridNo + " rfidSn -> " + rfidSn + " timestamp -> " + timestamp);
		
		StorageGridPurchaserNews sgpn = null;
		Date currentDate = new Date();

		//查找送货信息是否已经存在
		Query queryExist = entityManager.createQuery("select sgpn from StorageGridPurchaserNews sgpn where sgpn.closing = 0 and sgpn.storageGrid.gridNum = :gridNum and sgpn.deviceSn = :deviceSn and sgpn.rfidSn = :rfidSn");
		List<StorageGridPurchaserNews> deliveryRecordExist = queryExist.setParameter("gridNum", gridNo).setParameter("deviceSn", deviceSn).setParameter("rfidSn", rfidSn).getResultList();

		//如果存在，直接返回会员ID及取货密码
		if (null != deliveryRecordExist && deliveryRecordExist.size() > 0){
			List<ProductBatch> productBatchs = entityManager.createQuery("select pb from ProductBatch pb where pb.rfidSn = '" + rfidSn + "'").getResultList();
			logger.info("Receive Repeat delivery info ...");
			return new String[] {deliveryRecordExist.get(0).getCardNumber(), productBatchs.get(0).getPasswd()};
		}

		//确定配送仓状态是否错误
		Query query = entityManager.createQuery("select sgpn from StorageGridPurchaserNews sgpn where sgpn.closing = 0 and sgpn.storageGrid.gridNum = :gridNum and sgpn.deviceSn = :deviceSn");
		List<StorageGridPurchaserNews> oldsgpns = query.setParameter("gridNum", gridNo).setParameter("deviceSn", deviceSn).getResultList();

		// 修改历史数据并察看当前货号是否已经存在
		for (StorageGridPurchaserNews oldsgpn : oldsgpns) {
			logger.info("Current storage grid used! orderInfoNum -> " + oldsgpn.getOrderInformationNumber());

			if (oldsgpn.getRfidSn().equals(rfidSn))
				sgpn = oldsgpn;
			else {
				oldsgpn.setTakeawayTime(currentDate);
				oldsgpn.setClosing(1);
				oldsgpn.setPick(1);
				entityManager.merge(oldsgpn);

				// 插入取货记录
				if (oldsgpn.getRefund() == 0) {
					PickRecords pickRecords = new PickRecords();
					pickRecords.setCardNumber(oldsgpn.getCardNumber());
					pickRecords.setFlag(true);
					pickRecords.setInsertTime(DateTimeHelper.dateTimeToStr(currentDate, DateTimeHelper.DEFAULT_DATE_TIME_FORMAT));
					pickRecords.setOrderInformationNumber(oldsgpn.getOrderInformationNumber());
					pickRecords.setRfidSn(oldsgpn.getRfidSn());
					pickRecords.setGridNum(gridNo);
					entityManager.persist(pickRecords);

					// 修改配送单状态
					entityManager.createNativeQuery("update order_information set transactions = 5 where number = :orderNumber").setParameter("orderNumber", oldsgpn.getOrderInformationNumber()).executeUpdate();
				} else if (oldsgpn.getRefund() == 1) {
					RefundPickRecords refundPickRecords = new RefundPickRecords();
					refundPickRecords.setCardNumber(oldsgpn.getCardNumber());
					refundPickRecords.setFlag(true);
					refundPickRecords.setPickTime(currentDate);
					refundPickRecords.setOrderInfoNumber(oldsgpn.getOrderInformationNumber());
					refundPickRecords.setRfidSn(oldsgpn.getRfidSn());
					refundPickRecords.setGridNumber(gridNo);
					entityManager.persist(refundPickRecords);

					// 修改配送单状态
					entityManager.createNativeQuery("update refund_order_info set transactions = 3 where order_info_number = :orderNumber").setParameter("orderNumber", oldsgpn.getOrderInformationNumber()).executeUpdate();
				}

				entityManager.flush();
			}
		}

		List<OrderInformation> orderInfos = entityManager.createQuery("select oi from OrderInformation oi inner join oi.productBatchs pb where oi.deleted = 0 and pb.deleted = 0 and pb.rfidSn = :rfidSn").setParameter("rfidSn", rfidSn).getResultList();
		StorageGrid storageGrid = null;
		if (orderInfos.size() != 1)
			return new String[] { "000000000", "000000000" };

		OrderInformation orderInfo = orderInfos.get(0);
		
		workflowMessageLocal.createWorkflowInfo(orderInfo, 3, "货品已送至" + orderInfo.getLockers().getLocation().getDescription() + orderInfo.getLockers().getLockersName(), DateTimeHelper.strToDateTime(DateTimeHelper.dateTimeToStr(currentDate, DateTimeHelper.DEFAULT_YEAR_FORMAT) + CommEntryUtil.getFormatStr(timestamp, 10), DateTimeHelper.DEFAULT_DATE_TIME_NOT_SPACE_FORMAT), "系统", 3);

		//更新配送地址
		if (null == orderInfo.getLockers().getDevice()) {
			List<Lockers> lockersList = entityManager.createQuery("select l from Lockers l where l.device is not null and l.deleted = 0 and l.device.deviceSn = :deviceSn").setParameter("deviceSn", deviceSn).getResultList();
			if (null != lockersList)
				if (lockersList.size() == 1) {
					orderInfo.setLockers(lockersList.get(0));
					entityManager.merge(orderInfo);
					entityManager.flush();
				}
		} else if (!orderInfo.getLockers().getDevice().getDeviceSn().equals(deviceSn)) {
			List<Lockers> lockersList = entityManager.createQuery("select l from Lockers l where l.device is not null and l.deleted = 0 and l.device.deviceSn = :deviceSn").setParameter("deviceSn", deviceSn).getResultList();
			if (null != lockersList)
				if (lockersList.size() == 1) {
					orderInfo.setLockers(lockersList.get(0));
					entityManager.merge(orderInfo);
					entityManager.flush();
				}

		}

		for (StorageGrid sg : orderInfo.getLockers().getStorageGrids())
			if (sg.getGridNum() == gridNo) {
				storageGrid = sg;
				break;
			}

		if (null == sgpn) {
			// 组织配送信息
			sgpn = new StorageGridPurchaserNews();
			sgpn.setStorageGrid(storageGrid);
			sgpn.setCardNumber(orderInfo.getPurchaser().getCardInfo().getCardNumber());
			sgpn.setDelivery(1);
			sgpn.setClosing(0);
			sgpn.setArrivalTime(currentDate);
			sgpn.setPick(0);
			sgpn.setRfidSn(rfidSn);
			sgpn.setPurchaser(orderInfo.getPurchaser());
			sgpn.setLockersId(orderInfo.getLockers().getLockersId());
			sgpn.setLocationId(orderInfo.getLockers().getLocation().getLocationId());
			sgpn.setOrderInformationNumber(orderInfo.getNumber());
			sgpn.setGroupId(orderInfo.getGroup().getGroupId());
			sgpn.setDeviceSn(deviceSn);
			sgpn.setRefund(0);
			entityManager.persist(sgpn);

			// 组织配送记录信息
			DeliveryRecord deliveryRecord = new DeliveryRecord();
			deliveryRecord.setCardNumber(orderInfo.getPurchaser().getCardInfo().getCardNumber());
			deliveryRecord.setRfidSn(rfidSn);
			deliveryRecord.setGridNum(gridNo);
			deliveryRecord.setInsertTime(DateTimeHelper.dateTimeToStr(currentDate, DateTimeHelper.DEFAULT_DATE_TIME_FORMAT));
			deliveryRecord.setLocation(orderInfo.getLockers().getLocation().getVilliage().getName() + orderInfo.getLockers().getLocation().getName() + orderInfo.getLockers().getLockersName());
			deliveryRecord.setPurchaserName(orderInfo.getPurchaser().getName());
			entityManager.persist(deliveryRecord);

			entityManager.flush();
		}

		Object done = entityManager.createQuery("select count(sgpn) from StorageGridPurchaserNews sgpn where sgpn.refund = 0 and sgpn.orderInformationNumber = :number").setParameter("number", orderInfo.getNumber()).getSingleResult();

		Set<ProductBatch> productBatchs = orderInfo.getProductBatchs();

		for (Iterator<ProductBatch> it = productBatchs.iterator(); it.hasNext();) {
			ProductBatch productBatch = it.next();
			if (productBatch.isDeleted())
				it.remove();
		}

		// 判断当前配送单商品是否全部送货完成
		if (productBatchs.size() == Integer.parseInt(done.toString())) {
			logger.info("All products delivery done ... ");
			// 修改配送单状态为送货完毕
			orderInfo.setTransactions(6);
			orderInfo.setEffective(true);
			entityManager.merge(orderInfo);
			
			Iterator<OrderInformation> it = orderInfo.getOrderInformations().iterator();
			
			while (it.hasNext()) {
				OrderInformation orderInformation = (OrderInformation) it.next();
				
				if (!orderInformation.isDeleted()){
					orderInformation.setTransactions(6);
					entityManager.merge(orderInformation);
				}
			}
			
			entityManager.flush();
			
			if (orderInfo.getGroup().getGroupSn().equals("063") && orderInfo.getGroup().getAppCode().equals("LFsdnFmWpv")){
				
				String groupId = String.valueOf(orderInfo.getGroup().getGroupId());
				
				WebServiceSoapProxy proxy = new WebServiceSoapProxy("http://oss.dingxian365.com/public/WebService.asmx?wsdl");
				String orderCode = orderInfo.getNumber().substring(groupId.length(), orderInfo.getNumber().length());
				try {
					ResultInfo resultInfo = proxy.WS_UpdateOrderDeliveryStatus(orderCode, "7HZ4P95UNU", "G4POWFWI33W6KFPSPQ4AQ89X6BZ0CI");
					logger.info("Result -> " + resultInfo.isResult_IsSuccess() + "Content -> " + resultInfo.getResult_Note());
				} catch (RemoteException e) {
					logger.error("Remote invoke fail\n" + e.getMessage());
				}
			}

		}

		String passwd = "";
		String location="";

		// 获取RFID
		for (ProductBatch productBatch : productBatchs)
			if (productBatch.getRfidSn().equals(rfidSn)) {
				passwd = productBatch.getPasswd();
				break;
			}

		Map<String, Object> informMap = informMessage.queryInformMessage(orderInfo.getPurchaser().getLanguage(), 2, orderInfo.getOrderType());
		
		Object[] objs = null;
		String key = "" + orderInfo.getPurchaser().getLanguage() + 2 + orderInfo.getOrderType();
		
		if (orderInfo.getOrderType().intValue() == 1) {
			location=orderInfo.getLockers().getLocation().getDescription()+orderInfo.getLockers().getLockersName();
			//objs = new Object[]{orderInfo.getLockers().getLocation().getDescription() + orderInfo.getLockers().getLockersName(), done.toString(), productBatchs.size(), passwd, orderInfo.getGroup().getHotline()};
			objs = new Object[]{orderInfo.getLockers().getLocation().getDescription() + orderInfo.getLockers().getLockersName(), passwd};
		} else if (orderInfo.getOrderType().intValue() == 2) {
			location=orderInfo.getExpressInfo().getName()+orderInfo.getLockers().getLocation().getDescription();
			//objs = new Object[]{orderInfo.getExpressInfo().getName(), orderInfo.getLockers().getLocation().getDescription(), orderInfo.getLockers().getLockersName(), passwd};
			objs = new Object[]{ orderInfo.getLockers().getLocation().getDescription()+orderInfo.getLockers().getLockersName(), passwd};
		}
		
		String phone = orderInfo.getPurchaser().getPhone();
		String email = orderInfo.getPurchaser().getEmail();
		
		if (null != phone && !"".equals(phone) && informMap.containsKey(InformMessageLocal.SMS_INFORM)){
			String message = ((SmsInfo)informMap.get(InformMessageLocal.SMS_INFORM)).getSmsContent();
			
			message = MessageFormat.format(message, objs);
			
			logger.info("SMS message -> " + message);
			
			//new SMSScheduler(phone, message, objs, key, orderInfo.getGroup().getSmsChannel(), orderInfo.getGroup().getName(), true).start();
			String params="{\"address\":\""+location+"\",\"passwd\":\""+passwd+"\"}";
			new AlidayuSMS(phone,"SMS_5450197","到货通知",params,message,new SaveSmsInfo()).start();
			
			workflowMessageLocal.createWorkflowInfo(orderInfo.getNumber(), 1, "发送送货信息...", DateTimeHelper.strToDateTime(DateTimeHelper.dateTimeToStr(new Date(), DateTimeHelper.DEFAULT_YEAR_FORMAT) + CommEntryUtil.getFormatStr(timestamp, 10), DateTimeHelper.DEFAULT_DATE_TIME_NOT_SPACE_FORMAT), "系统", 4);
		} else if (null != email && !"".equals(email) && informMap.containsKey(InformMessageLocal.EMAIL_INFORM)){
			EmailInfo emailInfo = (EmailInfo) informMap.get(InformMessageLocal.EMAIL_INFORM);
			
			String message = emailInfo.getContent();
			
			message = MessageFormat.format(message, objs);
			
			logger.info("E-MAIL message -> " + message);
			
			new EMAILScheduler(email, emailInfo.getTitle(), message).start();
			
			workflowMessageLocal.createWorkflowInfo(orderInfo.getNumber(), 1, "发送送货信息...", DateTimeHelper.strToDateTime(DateTimeHelper.dateTimeToStr(new Date(), DateTimeHelper.DEFAULT_YEAR_FORMAT) + CommEntryUtil.getFormatStr(timestamp, 10), DateTimeHelper.DEFAULT_DATE_TIME_NOT_SPACE_FORMAT), "系统", 4);
		}

		String[] results = { orderInfo.getPurchaser().getCardInfo().getCardNumber(), passwd };

		logger.info("Exce result -> " + results[0] + "  " + results[1]);

		return results;
	}

}
